﻿using Newtonsoft.Json;
using System.Net.Http.Headers;

namespace Wechat_PublicNumber.Common
{
    [Injection(DIPattern.Singleton)]
    public class HttpClinetHelper
    {
        [Autowired]
        private ILog _logger;

        [Autowired]
        private IHttpClientFactory _clientFactory;

        public async Task<ResponeModel> JsonPost<ResponeModel>(object body, string url) where ResponeModel : class
        {
            ResponeModel responeModel = null;
            string responeModelString = string.Empty;
            var parmString = JsonConvert.SerializeObject(body);
            var httpContent = new StringContent(parmString);

            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            using (var client = _clientFactory.CreateClient())
            {
                using (var responeMessage = await client.PostAsync(url, httpContent))
                {

                    if (responeMessage != null && responeMessage.Content != null)
                    {
                        responeModelString = await responeMessage.Content.ReadAsStringAsync();
                        responeModel = ConvertStringToResponeModel<ResponeModel>(responeModelString);
                    }

                    if (responeModel == null)
                        _logger.Error($"POST 本次调用未返回Respone，Url：{url}\nParam:{parmString}");
                    else
                        _logger.Info($"POST 调用成功，Url：{url}\nParam:{parmString}\nRespone:{responeModelString}");

                    return responeModel;
                }
            }
        }

        public async Task<ResponeModel> JsonGet<ResponeModel>(string url) where ResponeModel : class
        {
            ResponeModel responeModel = null;
            string responeModelString = string.Empty;
            using (var client = _clientFactory.CreateClient())
            {
                using (var responeMessage = await client.GetAsync(url))
                {
                    if (responeMessage != null && responeMessage.Content != null)
                    {
                        responeModelString = await responeMessage.Content.ReadAsStringAsync();
                        responeModel = ConvertStringToResponeModel<ResponeModel>(responeModelString);
                    }

                    if (responeModel == null)
                        _logger.Error($"GET 本次调用未返回Respone，Url：{url}");
                    else
                        _logger.Info($"GET 调用成功，Url：{url}\nRespone:{responeModelString}");

                    return responeModel;
                }
            }
        }

        public async Task<ResponeModel> UploadMedia<ResponeModel>(string url, string filePath, string fileName) where ResponeModel : class
        {
            ResponeModel responeModel = null;
            string responeModelString = string.Empty;
            using (var client = _clientFactory.CreateClient())
            {
                var boundary = DateTime.Now.Ticks.ToString("X");
                client.DefaultRequestHeaders.Remove("Expect");
                client.DefaultRequestHeaders.Remove("Connection");
                using (var httpContent = new MultipartFormDataContent(boundary))
                {
                    httpContent.Headers.Remove("Content-Type");
                    httpContent.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary);

                    var fileStream = File.Open(filePath, FileMode.Open);

                    byte[] fileByte = new byte[fileStream.Length];

                    await fileStream.ReadAsync(fileByte);
                    fileStream.Close();
                    fileStream.Dispose();
                    using (var contentByte = new ByteArrayContent(fileByte))
                    {

                        httpContent.Add(contentByte);
                        contentByte.Headers.Remove("Content-Disposition");
                        contentByte.Headers.TryAddWithoutValidation("Content-Disposition", $"form-data; name=\"media\";filename=\"{fileName}\"" + "");
                        contentByte.Headers.Remove("Content-Type");
                        contentByte.Headers.TryAddWithoutValidation("Content-Type", "image/png");

                        using (var responeMessage = await client.PostAsync(url, httpContent))
                        {
                            if (responeMessage != null && responeMessage.Content != null)
                            {
                                responeModelString = await responeMessage.Content.ReadAsStringAsync();
                                responeModel = ConvertStringToResponeModel<ResponeModel>(responeModelString);
                            }

                            if (responeModel == null)
                                _logger.Error($"POST 本次调用未返回Respone，Url：{url}");
                            else
                                _logger.Info($"POST 调用成功，Url：{url}\nRespone:{responeModelString}");

                            return responeModel;
                        }
                    }
                }
            }
        }

        private ResponeModel ConvertStringToResponeModel<ResponeModel>(string responeString) where ResponeModel : class
        {
            try
            {
                if (string.IsNullOrEmpty(responeString)) return null;
                if (typeof(ResponeModel).Name == "String") return (ResponeModel)(object)responeString;
                else return JsonConvert.DeserializeObject<ResponeModel>(responeString);
            }
            catch
            {
                _logger.Error($"返回respone：{responeString}");
                throw;
            }
        }
    }
}
